<!doctype html>
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>2.0 RC1 - FreeMarker 手册</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="FreeMarker 手册">
<meta property="og:title" content="2.0 RC1">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://freemarker.org/docs/versions_2_0RC1.html">
<link rel="canoical" href="http://freemarker.org/docs/versions_2_0RC1.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css">
</head>
<body itemscope itemtype="https://schema.org/Code">
    <meta itemprop="url" content="http://freemarker.org/docs/">
    <meta itemprop="name" content="FreeMarker 手册">

  <!--[if lte IE 9]>
  <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
  <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner">            <img itemprop="image" src="logo.png" alt="FreeMarker">
</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="http://freemarker.org/docs/api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://sourceforge.net/p/freemarker/bugs/new/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="toc.html" class="navigation-header">Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="toc.html"><span itemprop="name">FreeMarker 手册</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app.html"><span itemprop="name">附录</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">版本历史</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_0RC1.html"><span itemprop="name">2.0 RC1</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div>    <div class="main-content site-width">
      <div class="content-wrapper">
  <div id="table-of-contents-wrapper" class="col-left">
      <script>var breadcrumb = ["FreeMarker 手册","附录","版本历史","2.0 RC1"];</script>
      <script src="toc.js"></script>
      <script src="docgen-resources/main.min.js"></script>
  </div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_0RC2.html"><span>Previous</span></a><a class="paging-arrow next" href="app_install.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_0RC1" itemprop="headline">2.0 RC1</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_270" data-menu-target="autoid_270">Support for Numerical operations, both arithmetic and
boolean, as well as numerical ranges.</a></li><li><a class="page-menu-link" href="#autoid_271" data-menu-target="autoid_271">API Changes</a></li><li><a class="page-menu-link" href="#autoid_272" data-menu-target="autoid_272">Syntactical Miscellany</a></li></ul> </div><p>The first public release of FreeMarker 2.0 was on 18 March 2002.
        Here is a summary of the changes in the Lazarus release, with respect
        to the last stable release of FreeMarker Classic.</p><p><em>NOTA BENE</em>:</p><p>Despite the changes delineated above, the Lazarus release is
        almost entirely backward-compatible with FreeMarker Classic. We
        believe that <em>most</em> existing code and templates
        that work under FreeMarker Classic will continue working under
        Lazarus, with at most minimal changes. In practice, the most common
        cases where legacy template code is broken will be where assumptions
        were made about numbers and strings being equivalent. Note that in
        FreeMarker 2, 2 + 2 does not result in &quot;22&quot;. The String &quot;1&quot; and the
        number 1 are entirely different animals and thus, any code will be
        broken if it relies on the boolean expression (&quot;1&quot;==1) being true.
        There is a &quot;classic compatibility mode&quot; that can be set via:
        <code class="inline-code">Template.setClassCompatibility()</code> that can be set so
        that Lazarus emulates some of the quirky behavior of FreeMarker
        Classic. However, any code that relied on the above &quot;features&quot; of
        FreeMarker classic really should be reworked. You are less likely to
        run into the other incompatibilities that are listed above. If you
        come across any other anomalies, please do tell us about them.</p>
          



<h2 class="content-header header-section2" id="autoid_270">Support for Numerical operations, both arithmetic and
          boolean, as well as numerical ranges.</h2>


          <ul>
            <li>
              <p>Scalars can now be either strings or numbers. (In
              FreeMarker Classic all scalars were strings.) The basic
              operations allowed are addition, subtraction, multiplication,
              division, and modulus using the <code class="inline-code">+</code>,
              <code class="inline-code">-</code>, <code class="inline-code">*</code>,
              <code class="inline-code">/</code>, and <code class="inline-code">%</code> operators
              respectively. Arbitrary-precision arithmetic with integers and
              floating point numbers are provided. Though our goal is
              definitely to follow the principle of least surprise, for
              backward compatibility, the <code class="inline-code">+</code> operator still
              is used for string concatenation. If either the left hand side
              or the right hand side of <code class="inline-code">lhs + rhs</code> is
              non-numerical, we revert to interpreting this as string
              concatenation. Thus, in FreeMarker 2, 2+2 evaluates to the
              number 4, while any of &quot;2&quot;+2 or 2+&quot;2&quot; or &quot;2&quot;+&quot;2&quot; evaluate to the
              string &quot;22&quot;. In FreeMarker Classic, rather embarrassingly, all
              of the above, including 2+2, evaluated to the string &quot;22&quot;. An
              attempt to use any other arithmetic operator besides the
              <code class="inline-code">+</code> with non-numerical operands will cause an
              exception to be thrown.</p>
            </li>

            <li>
              <p>Output of a numerical expression can be made explicit via
              the alternative <code class="inline-code">#{....}</code> syntax. If the
              expression within the curly parentheses does not evaluate to a
              numerical value, an exception is thrown. The older ${....}
              syntax can evaluate to either a number or a string. In general,
              if, for logical reasons, the output <em>must</em> be
              numerical, it is preferable to use the #{...} syntax, since it
              adds an extra sanity check. Note that if, by some miracle, the
              character sequence &quot;#{&quot; occurs in your template, you will have
              to use a workaround to prevent problems. (The &lt;noparse&gt;
              directive is one possibility.)</p>
            </li>

            <li>
              <p>In this release, there is a facility for specifying the
              number of digits to show after the decimal point. The following
              code specifies to show at least 3 digits after the decimal point
              but not more than 6. This is optional. This option is only
              available if you use the #{...} syntax.</p>

              

<div class="code-wrapper"><pre class="code-block code-template">#{foo + bar ; m3M6}  </pre></div>

              <p>(Note that the above is something of a stopgap measure.
              Future releases will move toward supporting fully
              internationalization and localization of number and currency
              formatting.</p>
            </li>

            <li>
              <p>Numerical expressions can be used in boolean expressions
              via the comparison operators: <code class="inline-code">lt</code>,
              <code class="inline-code">gt</code>, <code class="inline-code">lte</code>, and
              <code class="inline-code">gte</code>. In the web space, where FreeMarker is
              most used in practice, using the more natural operators such as
              &lt; and &gt; would tend to confuse HTML-oriented editors. An
              attempt to compare non-numerical expressions using these
              operators leads to a <code class="inline-code">TemplateException</code> being
              thrown. If, by some coincidence, you have variables named &quot;lt&quot;,
              &quot;gt&quot;, &quot;lte&quot;, or &quot;gte&quot;, you will have to change their names,
              since they are now keywords in the language.</p>
            </li>

            <li>
              <p>Numerical ranges are supported.</p>

              

<div class="code-wrapper"><pre class="code-block code-template">&lt;#list 1990..2001 as year&gt;
  blah blah in the year ${year} blah
&lt;/#list&gt; </pre></div>

              <p>The left hand and right hand sides of the
              <code class="inline-code">..</code> operator must be numerical, or an
              exception is thrown. They also need not be literal numbers, but
              can be more complex expressions that evaluate to a numerical
              scalar value. Note that it is also possible to write a range
              that descends in value:</p>

              

<div class="code-wrapper"><pre class="code-block code-template">&lt;#list 2001..1990 as year&gt;
  blah blah in the year ${year} blah blah
&lt;/#list&gt;  </pre></div>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_271">API Changes</h2>


          <ul>
            <li>
              <p>The <code class="inline-code">TemplateNumberModel</code> interface and
              the <code class="inline-code">SimpleNumber</code> implementation were added to
              support exposing numerical values.</p>
            </li>

            <li>
              <p>The <code class="inline-code">TemplateListModel</code> API in FreeMarker
              Classic had some design problems -- particularly in terms of
              supporting thread-safe code. It has been deprecated in favor of
              the following API&#39;s: <code class="inline-code">TemplateCollectionModel</code>
              and <code class="inline-code">TemplateSequenceModel</code>. The
              <code class="inline-code">SimpleList</code> class was refactored to implement
              the above interfaces (and paradoxically, does not implement the
              TemplateListModel interface.) Code that uses the deprecated
              <code class="inline-code">TemplateListModel</code> should be
              refactored.</p>
            </li>

            <li>
              <p>The Expose Package by Attila Szegedi has been made an
              integral part of the FreeMarker distribution and is now under
              the freemarker.ext.* hierarchy. This package provides advanced
              models for representing arbitrary Java objects as template
              models, for representing XML documents as template models, as
              well as classes to facilitate the integration of FreeMarker with
              servlets and Ant.</p>
            </li>

            <li>
              <p>In FreeMarker Classic, there were some utility classes
              such as <code class="inline-code">freemarker.template.utility.Addition</code>
              etcetera that existed as workarounds for the lack of numerical
              operations in FreeMarker. Those have been removed and will
              probably not be missed.</p>
            </li>

            <li>
              <p>In FreeMarker Classic, the <code class="inline-code">SimpleScalar</code>
              object was mutable, it had a <code class="inline-code">setValue</code> method.
              This was fairly obviously a design mistake. Any code that relied
              on this must be refactored. Note that in this release, both
              <code class="inline-code">SimpleScalar</code> and the newly introduced
              <code class="inline-code">SimpleNumber</code> are both immutable and
              final.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_272">Syntactical Miscellany</h2>


          <ul>
            <li>
              <p>The if-elseif-else syntax was introduced. FreeMarker
              classic only had if-else. This construct should probably (in the
              opinion of the author of this document -- Revusky) be used in
              preference to switch-case since the switch-case with
              fall-through is a notoriously error-prone construct for most
              mortal men.</p>
            </li>

            <li>
              <p>You can now do a multiple assignment in one
              &lt;assign...&gt; directive. For example: <code class="inline-code">&lt;assign x
              = 1, y = price*items, message=&quot;foo&quot;&gt;</code></p>
            </li>

            <li>
              <p>A scalar will no longer be interpreted as a one-item list
              in a &lt;list...&gt; or &lt;#foreach...&gt; block. If you have
              code that relied on this feature, there is an easy workaround,
              since you can simply define a list literal with exactly one
              item.</p>

              

<div class="code-wrapper"><pre class="code-block code-template"> &lt;assign y=[x]&gt;
 <strong>and then...</strong>
 &lt;list y as item&gt;...&lt;/list&gt; </pre></div>
            </li>
          </ul>
        <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_0RC2.html"><span>Previous</span></a><a class="paging-arrow next" href="app_install.html"><span>Next</span></a></div></div></div></div>      </div>
    </div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="http://freemarker.org/index.html">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/nanlei/freemarker/tree/manual-zh-2.3-gae/src/manual">Chinese Manual on Github</a></li><li><a href="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://sourceforge.net/p/freemarker/bugs/new/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"><p><span class="generated-for-product">Generated for: Freemarker 2.3.23</span><span class="last-updated"> Last generated:
<time itemprop="dateModified" datetime="2015-09-18T14:38:51Z" title="Friday, September 18, 2015 2:38:51 PM GMT">2015-09-18 14:38:51 GMT</time></span></p> <p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2015
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://freemarker.org">The FreeMarker Project</a>. All rights reserved. </p>
</div></div></div></body>
</html>
